Skip to main content

compio_driver\sys\op\managed/
fallback.rs

1use std::io;
2
3use compio_buf::{IntoInner, IoBuf, IoBufMut, SetLen};
4use rustix::net::RecvFlags;
5use socket2::SockAddr;
6
7use crate::{
8    AsFd, BufferPool, BufferRef,
9    op::{RecvMsg, TakeBuffer},
10    sys::op::{Read, ReadAt, Recv, RecvFrom},
11};
12
13/// Read a file at specified position into managed buffer.
14pub struct ReadManagedAt<S> {
15    pub(crate) op: ReadAt<BufferRef, S>,
16}
17
18impl<S> ReadManagedAt<S> {
19    /// Create [`ReadManagedAt`].
20    pub fn new(fd: S, offset: u64, pool: &BufferPool, len: usize) -> io::Result<Self> {
21        Ok(Self {
22            op: ReadAt::new(fd, offset, pool.pop()?.with_capacity(len)),
23        })
24    }
25}
26
27impl<S> TakeBuffer for ReadManagedAt<S> {
28    type Buffer = BufferRef;
29
30    fn take_buffer(self) -> Option<BufferRef> {
31        Some(self.op.into_inner())
32    }
33}
34
35/// Read a file into managed buffer.
36pub struct ReadManaged<S> {
37    pub(crate) op: Read<BufferRef, S>,
38}
39
40impl<S> ReadManaged<S> {
41    /// Create [`ReadManaged`].
42    pub fn new(fd: S, pool: &BufferPool, len: usize) -> io::Result<Self> {
43        Ok(Self {
44            op: Read::new(fd, pool.pop()?.with_capacity(len)),
45        })
46    }
47}
48
49impl<S> TakeBuffer for ReadManaged<S> {
50    type Buffer = BufferRef;
51
52    fn take_buffer(self) -> Option<BufferRef> {
53        Some(self.op.into_inner())
54    }
55}
56
57/// Receive data from remote into managed buffer.
58///
59/// It is only used for socket operations. If you want to read from a pipe,
60/// use [`ReadManaged`].
61pub struct RecvManaged<S> {
62    pub(crate) op: Recv<BufferRef, S>,
63}
64
65impl<S> RecvManaged<S> {
66    /// Create [`RecvManaged`].
67    pub fn new(fd: S, pool: &BufferPool, len: usize, flags: RecvFlags) -> io::Result<Self> {
68        Ok(Self {
69            op: Recv::new(fd, pool.pop()?.with_capacity(len), flags),
70        })
71    }
72
73    /// This method sets the `IORING_RECVSEND_POLL_FIRST` flag in the `ioprio`
74    /// of the SQE on the IO_URING driver.
75    // This method has been added here for the sake of API compatibility.
76    pub fn poll_first(&mut self) {}
77}
78
79impl<S> TakeBuffer for RecvManaged<S> {
80    type Buffer = BufferRef;
81
82    fn take_buffer(self) -> Option<BufferRef> {
83        Some(self.op.into_inner())
84    }
85}
86
87/// Receive data and source address into managed buffer.
88pub struct RecvFromManaged<S: AsFd> {
89    pub(crate) op: RecvFrom<BufferRef, S>,
90}
91
92impl<S: AsFd> RecvFromManaged<S> {
93    /// Create [`RecvFromManaged`].
94    pub fn new(fd: S, pool: &BufferPool, len: usize, flags: RecvFlags) -> io::Result<Self> {
95        Ok(Self {
96            op: RecvFrom::new(fd, pool.pop()?.with_capacity(len), flags),
97        })
98    }
99
100    /// This method sets the `IORING_RECVSEND_POLL_FIRST` flag in the `ioprio`
101    /// of the SQE on the IO_URING driver.
102    // This method has been added here for the sake of API compatibility.
103    pub fn poll_first(&mut self) {}
104}
105
106impl<S: AsFd> TakeBuffer for RecvFromManaged<S> {
107    type Buffer = (BufferRef, Option<SockAddr>);
108
109    fn take_buffer(self) -> Option<Self::Buffer> {
110        Some(self.op.into_inner())
111    }
112}
113
114/// Receive data into managed buffer, and ancillary data into control buffer.
115pub struct RecvMsgManaged<C: IoBufMut, S: AsFd> {
116    pub(crate) op: RecvMsg<[BufferRef; 1], C, S>,
117}
118
119impl<C: IoBufMut, S: AsFd> RecvMsgManaged<C, S> {
120    /// Create [`RecvMsgManaged`].
121    pub fn new(
122        fd: S,
123        pool: &BufferPool,
124        len: usize,
125        control: C,
126        flags: RecvFlags,
127    ) -> io::Result<Self> {
128        Ok(Self {
129            op: RecvMsg::new(fd, [pool.pop()?.with_capacity(len)], control, flags),
130        })
131    }
132
133    /// This method sets the `IORING_RECVSEND_POLL_FIRST` flag in the `ioprio`
134    /// of the SQE on the IO_URING driver.
135    // This method has been added here for the sake of API compatibility.
136    pub fn poll_first(&mut self) {}
137}
138
139impl<C: IoBufMut, S: AsFd> TakeBuffer for RecvMsgManaged<C, S> {
140    type Buffer = ((BufferRef, C), Option<SockAddr>, usize);
141
142    fn take_buffer(self) -> Option<Self::Buffer> {
143        let (([buf], control), addr, len) = self.op.into_inner();
144        Some(((buf, control), addr, len))
145    }
146}
147
148/// Read a file at specified position into multiple managed buffers.
149pub type ReadMultiAt<S> = ReadManagedAt<S>;
150/// Read a file into multiple managed buffers.
151pub type ReadMulti<S> = ReadManaged<S>;
152/// Receive data from remote into multiple managed buffers.
153pub type RecvMulti<S> = RecvManaged<S>;
154
155/// Result of [`RecvFromMulti`].
156pub struct RecvFromMultiResult {
157    buffer: BufferRef,
158    addr: Option<SockAddr>,
159}
160
161impl RecvFromMultiResult {
162    #[doc(hidden)]
163    pub unsafe fn new(_: BufferRef) -> Self {
164        unreachable!("should not be called directly")
165    }
166
167    /// Get the payload data.
168    pub fn data(&self) -> &[u8] {
169        self.buffer.as_init()
170    }
171
172    /// Get the source address if applicable.
173    pub fn addr(&self) -> Option<SockAddr> {
174        self.addr.clone()
175    }
176}
177
178impl IntoInner for RecvFromMultiResult {
179    type Inner = BufferRef;
180
181    fn into_inner(self) -> Self::Inner {
182        self.buffer
183    }
184}
185
186/// Receive data and source address multi times into multiple managed buffers.
187pub struct RecvFromMulti<S: AsFd> {
188    pub(crate) op: RecvFromManaged<S>,
189    pub(crate) len: usize,
190}
191
192impl<S: AsFd> RecvFromMulti<S> {
193    /// Create [`RecvFromMulti`].
194    pub fn new(fd: S, pool: &BufferPool, flags: RecvFlags) -> io::Result<Self> {
195        Ok(Self {
196            op: RecvFromManaged::new(fd, pool, 0, flags)?,
197            len: 0,
198        })
199    }
200}
201
202impl<S: AsFd> TakeBuffer for RecvFromMulti<S> {
203    type Buffer = RecvFromMultiResult;
204
205    fn take_buffer(self) -> Option<Self::Buffer> {
206        let (mut buffer, addr) = self.op.take_buffer()?;
207        unsafe { buffer.advance_to(self.len) };
208        Some(RecvFromMultiResult { buffer, addr })
209    }
210}
211
212/// Result of [`RecvMsgMulti`].
213pub struct RecvMsgMultiResult {
214    buffer: BufferRef,
215    control: BufferRef,
216    addr: Option<SockAddr>,
217}
218
219impl RecvMsgMultiResult {
220    #[doc(hidden)]
221    pub unsafe fn new(_: BufferRef, _: usize) -> Self {
222        unreachable!("should not be called directly")
223    }
224
225    /// Get the payload data.
226    pub fn data(&self) -> &[u8] {
227        self.buffer.as_init()
228    }
229
230    /// Get the source address if applicable.
231    pub fn addr(&self) -> Option<SockAddr> {
232        self.addr.clone()
233    }
234
235    /// Get the ancillary data.
236    pub fn ancillary(&self) -> &[u8] {
237        self.control.as_init()
238    }
239}
240
241impl IntoInner for RecvMsgMultiResult {
242    type Inner = BufferRef;
243
244    fn into_inner(self) -> Self::Inner {
245        self.buffer
246    }
247}
248
249/// Receive data, ancillary data and source address multi times into multiple
250/// managed buffers.
251pub struct RecvMsgMulti<S: AsFd> {
252    pub(crate) op: RecvMsgManaged<BufferRef, S>,
253    pub(crate) len: usize,
254}
255
256impl<S: AsFd> RecvMsgMulti<S> {
257    /// Create [`RecvMsgMulti`].
258    pub fn new(fd: S, pool: &BufferPool, control_len: usize, flags: RecvFlags) -> io::Result<Self> {
259        Ok(Self {
260            op: RecvMsgManaged::new(fd, pool, 0, pool.pop()?.with_capacity(control_len), flags)?,
261            len: 0,
262        })
263    }
264}
265
266impl<S: AsFd> TakeBuffer for RecvMsgMulti<S> {
267    type Buffer = RecvMsgMultiResult;
268
269    fn take_buffer(self) -> Option<Self::Buffer> {
270        let ((mut buffer, mut control), addr, control_len) = self.op.take_buffer()?;
271        unsafe { buffer.advance_to(self.len) };
272        unsafe { control.advance_to(control_len) };
273        Some(RecvMsgMultiResult {
274            buffer,
275            control,
276            addr,
277        })
278    }
279}